<template>
  <div class="app-container">
    <!-- 搜索表单 -->
    <el-form v-show="showSearch" ref="queryForm" :model="queryParams" :inline="true" class="search-form">
      <el-form-item label="商品名称" prop="name">
        <el-input v-model="queryParams.name" placeholder="请输入商品名称" clearable />
      </el-form-item>
      <el-form-item label="商品编号" prop="productNo">
        <el-input v-model="queryParams.productNo" placeholder="请输入商品编号" clearable />
      </el-form-item>
      <el-form-item label="品牌" prop="brandId">
        <el-select
          v-model="queryParams.brandId"
          placeholder="请选择品牌"
          clearable
          filterable
          remote
          :remote-method="handleBrandSearch"
          :loading="brandLoading"
        >
          <el-option v-for="item in brandOptions" :key="item.id" :label="item.name" :value="item.id" />
        </el-select>
      </el-form-item>
      <el-form-item label="分类" prop="categoryId">
        <el-select
          v-model="queryParams.categoryId"
          placeholder="请选择分类"
          clearable
          filterable
          remote
          :remote-method="handleCategorySearch"
          :loading="categoryLoading"
        >
          <el-option v-for="item in categoryOptions" :key="item.id" :label="item.name" :value="item.id" />
        </el-select>
      </el-form-item>
      <el-form-item label="商品状态" prop="status">
        <el-select v-model="queryParams.status" placeholder="请选择商品状态" clearable>
          <el-option v-for="dict in statusOptions" :key="dict.value" :label="dict.label" :value="dict.value" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 操作按钮区域 -->
    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button v-hasPermi="['product:product:add']" type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button v-hasPermi="['product:product:remove']" type="danger" plain icon="Delete" :disabled="multiple" @click="() => handleDelete()"
          >删除</el-button
        >
      </el-col>
      <right-toolbar v-model:showSearch="showSearch" @query-table="getList"></right-toolbar>
    </el-row>

    <!-- 数据表格 -->
    <div class="table-container">
      <el-table
        v-loading="loading"
        v-infinite-scroll="loadMore"
        :data="productList"
        :infinite-scroll-disabled="loading"
        :infinite-scroll-distance="10"
        :infinite-scroll-immediate="false"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="商品ID" align="center" prop="id" />
        <el-table-column label="商品名称" align="center" prop="name" show-overflow-tooltip />
        <el-table-column label="商品编号" align="center" prop="productNo" show-overflow-tooltip />
        <el-table-column label="品牌" align="center" prop="brandName">
          <template #default="scope">
            {{ scope.row.brandName || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="分类" align="center" prop="categoryName">
          <template #default="scope">
            {{ scope.row.categoryName || '-' }}
          </template>
        </el-table-column>
        <el-table-column label="价格" align="center">
          <template #default="scope">
            <div>售价：¥{{ scope.row.price }}</div>
            <div>原价：¥{{ scope.row.originalPrice }}</div>
          </template>
        </el-table-column>
        <el-table-column label="状态" align="center" prop="status">
          <template #default="scope">
            <el-tag :type="scope.row.status === 1 ? 'success' : 'info'">
              {{ scope.row.status === 1 ? '上架' : '下架' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="排序" align="center" prop="sort" />
        <el-table-column label="创建时间" align="center" prop="createTime" width="180">
          <template #default="scope">
            <span>{{ parseTime(scope.row.createTime) }}</span>
          </template>
        </el-table-column>
        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
          <template #default="scope">
            <el-button v-hasPermi="['product:product:edit']" link type="primary" icon="Edit" @click="handleUpdate(scope.row)">修改</el-button>
            <el-button v-hasPermi="['product:product:remove']" link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
            <el-button v-hasPermi="['product:product:edit']" link type="primary" icon="Setting" @click="handleDetail(scope.row)">设置详情</el-button>
            <el-button
              v-hasPermi="['product:product:edit']"
              link
              :type="scope.row.status === 1 ? 'warning' : 'success'"
              :icon="scope.row.status === 1 ? 'Bottom' : 'Top'"
              @click="handleStatus(scope.row)"
            >
              {{ scope.row.status === 1 ? '下架' : '上架' }}
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 加载状态提示 -->
      <div v-if="loadingMore" class="loading-more">
        <el-icon class="is-loading"><Loading /></el-icon>
        <span>加载中...</span>
      </div>
      <div v-if="!hasMore && productList.length > 0" class="no-more">没有更多数据了</div>

      <!-- 分页组件 -->
      <div class="pagination-container">
        <el-pagination
          v-model:current-page="queryParams.pageNum"
          v-model:page-size="queryParams.pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <!-- 添加或修改商品对话框 -->
    <el-dialog v-model="open" :title="title" width="700px" append-to-body>
      <el-form ref="productRef" :model="form" :rules="rules" label-width="100px" class="dialog-form">
        <el-form-item label="商品名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入商品名称" />
        </el-form-item>
        <el-form-item label="商品编号" prop="productNo">
          <el-input v-model="form.productNo" placeholder="请输入商品编号" />
        </el-form-item>
        <el-form-item label="商品价格" prop="price">
          <el-input-number v-model="form.price" :precision="2" :step="0.1" :min="0" />
        </el-form-item>
        <el-form-item label="商品原价" prop="originalPrice">
          <el-input-number v-model="form.originalPrice" :precision="2" :step="0.1" :min="0" />
        </el-form-item>
        <el-form-item label="品牌" prop="brandId">
          <el-select v-model="form.brandId" placeholder="请选择品牌" filterable remote :remote-method="handleBrandSearch" :loading="brandLoading">
            <el-option v-for="item in brandOptions" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="分类" prop="categoryId">
          <el-select
            v-model="form.categoryId"
            placeholder="请选择分类"
            filterable
            remote
            :remote-method="handleCategorySearch"
            :loading="categoryLoading"
          >
            <el-option v-for="item in categoryOptions" :key="item.id" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="排序" prop="sort">
          <el-input-number v-model="form.sort" :min="0" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue';
import { useRouter } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';
import type { FormInstance } from 'element-plus';
import { Loading, Setting, InfoFilled, Top, Bottom } from '@element-plus/icons-vue';
import { listProduct, getProduct, addProduct, updateProduct, delProduct, delProductBatch } from '@/api/product/product';
import { listBrand } from '@/api/product/brand';
import { listCategory } from '@/api/product/category';
import { getProductDetail, getProductDetailByProductId } from '@/api/product/detail';
import type { ProductVO, ProductForm, ProductQuery } from '@/api/product/product/types';
import type { BrandVO } from '@/api/product/brand/types';
import type { CategoryVO } from '@/api/product/category/types';

// 遮罩层
const loading = ref(false);
// 选中数组
const ids = ref<number[]>([]);
// 非单个禁用
const single = ref(true);
// 非多个禁用
const multiple = ref(true);
// 显示搜索条件
const showSearch = ref(true);
// 总条数
const total = ref(0);
// 商品表格数据
const productList = ref<ProductVO[]>([]);
// 弹出层标题
const title = ref('');
// 是否显示弹出层
const open = ref(false);

// 缓存品牌和分类数据
const brandCache = ref<Map<string, BrandVO[]>>(new Map());
const categoryCache = ref<Map<string, CategoryVO[]>>(new Map());

// 防抖函数
const debounce = (fn: Function, delay: number) => {
  let timer: NodeJS.Timeout | null = null;
  return (...args: any[]) => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(null, args);
    }, delay);
  };
};

// 品牌和分类搜索防抖
const brandSearchDebounce = ref<NodeJS.Timeout>();
const categorySearchDebounce = ref<NodeJS.Timeout>();

// 是否还有更多数据
const hasMore = ref(true);
// 是否正在加载更多
const loadingMore = ref(false);

// 状态数据字典
const statusOptions = [
  { value: 0, label: '下架' },
  { value: 1, label: '上架' }
];

// 品牌选项
const brandOptions = ref<BrandVO[]>([]);
// 分类选项
const categoryOptions = ref<CategoryVO[]>([]);

// 品牌和分类加载状态
const brandLoading = ref(false);
const categoryLoading = ref(false);

/** 品牌搜索 */
const handleBrandSearch = debounce(async (query: string) => {
  if (brandCache.value.has(query)) {
    brandOptions.value = brandCache.value.get(query) || [];
    return;
  }

  brandLoading.value = true;
  try {
    const res = await listBrand({
      pageNum: 1,
      pageSize: 100,
      name: query || undefined
    });
    if (res.code === 200) {
      brandOptions.value = res.rows;
      brandCache.value.set(query, res.rows);
    }
  } catch (error) {
    console.error('搜索品牌失败:', error);
  } finally {
    brandLoading.value = false;
  }
}, 300);

/** 分类搜索 */
const handleCategorySearch = debounce(async (query: string) => {
  if (categoryCache.value.has(query)) {
    categoryOptions.value = categoryCache.value.get(query) || [];
    return;
  }

  categoryLoading.value = true;
  try {
    const res = await listCategory({
      pageNum: 1,
      pageSize: 100,
      name: query || undefined
    });
    if (res.code === 200) {
      categoryOptions.value = res.rows;
      categoryCache.value.set(query, res.rows);
    }
  } catch (error) {
    console.error('搜索分类失败:', error);
  } finally {
    categoryLoading.value = false;
  }
}, 300);

/** 查询参数 */
const queryParams = reactive<ProductQuery>({
  pageNum: 1,
  pageSize: 10,
  name: undefined,
  productNo: undefined,
  brandId: undefined,
  categoryId: undefined,
  status: undefined
});

// 表单参数
const form = reactive<ProductForm>({
  id: undefined,
  productNo: '',
  name: '',
  price: 0,
  originalPrice: 0,
  brandId: 0,
  categoryId: 0,
  status: 0,
  sort: 0
});

// 表单引用
const productRef = ref<FormInstance>();

// 表单校验规则
const rules = {
  name: [{ required: true, message: '商品名称不能为空', trigger: 'blur' }],
  productNo: [{ required: true, message: '商品编号不能为空', trigger: 'blur' }],
  price: [{ required: true, message: '商品价格不能为空', trigger: 'blur' }],
  originalPrice: [{ required: true, message: '商品原价不能为空', trigger: 'blur' }],
  brandId: [{ required: true, message: '请选择品牌', trigger: 'change' }],
  categoryId: [{ required: true, message: '请选择分类', trigger: 'change' }],
  status: [{ required: true, message: '商品状态不能为空', trigger: 'change' }]
};

const router = useRouter();

/** 加载更多数据 */
const loadMore = async () => {
  if (!hasMore.value || loadingMore.value) return;

  loadingMore.value = true;
  try {
    queryParams.pageNum++;
    const res = await listProduct(queryParams);
    if (res.rows.length > 0) {
      productList.value = [...productList.value, ...res.rows];
    } else {
      hasMore.value = false;
    }
  } catch (error) {
    console.error('加载更多数据失败:', error);
  } finally {
    loadingMore.value = false;
  }
};

/** 查询商品列表 */
async function getList() {
  loading.value = true;
  try {
    const res = await listProduct(queryParams);
    productList.value = res.rows;
    total.value = res.total;
    hasMore.value = res.rows.length === queryParams.pageSize;
  } finally {
    loading.value = false;
  }
}

/** 取消按钮 */
function cancel() {
  open.value = false;
  reset();
}

/** 表单重置 */
function reset() {
  form.id = undefined;
  form.productNo = '';
  form.name = '';
  form.price = 0;
  form.originalPrice = 0;
  form.brandId = 1;
  form.categoryId = 1;
  form.status = 0;
  form.sort = 0;
}

/** 搜索按钮操作 */
function handleQuery() {
  queryParams.pageNum = 1;
  productList.value = [];
  hasMore.value = true;
  getList();
}

/** 重置按钮操作 */
function resetQuery() {
  queryParams.name = undefined;
  queryParams.productNo = undefined;
  queryParams.brandId = undefined;
  queryParams.categoryId = undefined;
  queryParams.status = undefined;
  handleQuery();
}

/** 多选框选中数据 */
function handleSelectionChange(selection: ProductVO[]) {
  ids.value = selection.map((item) => item.id);
  single.value = selection.length !== 1;
  multiple.value = !selection.length;
}

/** 新增按钮操作 */
function handleAdd() {
  reset();
  open.value = true;
  title.value = '添加商品';
}

/** 修改按钮操作 */
async function handleUpdate(row: ProductVO) {
  reset();
  const id = row.id || ids.value[0];
  try {
    loading.value = true;
    const res = await getProduct(id);
    Object.assign(form, {
      ...res.data,
      price: Number(res.data.price),
      originalPrice: Number(res.data.originalPrice),
      status: res.data.status
    });
    open.value = true;
    title.value = '修改商品';
  } catch (error) {
    console.error('获取商品详情失败:', error);
    ElMessage.error('获取商品详情失败');
  } finally {
    loading.value = false;
  }
}

/** 提交按钮 */
const submitForm = async () => {
  if (!productRef.value) return;

  try {
    await productRef.value.validate();
    const submitData = { ...form };
    // 新增时强制设置为下架状态
    if (!submitData.id) {
      submitData.status = 0;
    }

    if (submitData.id) {
      // 如果是修改，且要改为上架状态，需要检查是否有详情
      if (submitData.status === 1) {
        const hasDetail = await checkProductDetail(submitData.id);
        if (!hasDetail) {
          ElMessageBox.confirm('该商品尚未设置详情，设置详情后才能上架。是否立即去设置？', '提示', {
            confirmButtonText: '去设置',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            router.push({
              name: 'ProductDetail',
              params: { productId: submitData.id }
            });
          });
          return;
        }
      }
      await updateProduct(submitData as ProductVO);
      ElMessage.success('修改成功');
    } else {
      const res = await addProduct(submitData as ProductVO);
      ElMessage.success('新增成功');
      // 添加成功后提示用户去设置商品详情
      ElMessageBox.confirm('商品添加成功！请前往设置商品详情，否则商品将无法上架。', '提示', {
        confirmButtonText: '去设置',
        cancelButtonText: '稍后设置',
        type: 'warning'
      })
        .then(() => {
          // 跳转到商品详情页面

          router.push({
            name: 'ProductDetail',
            params: { productId: res.data }
          });
        })
        .catch(() => {
          // 用户选择稍后设置，不做任何操作
        });
    }
    open.value = false;
    getList();
  } catch (error) {
    console.error('提交失败:', error);
    ElMessage.error('表单验证失败或提交出错');
  }
};

/** 检查商品是否有详情 */
const checkProductDetail = async (productId: number) => {
  try {
    const response = await getProductDetailByProductId(productId);
    return !!response.data;
  } catch (error) {
    console.error('检查商品详情失败:', error);
    return false;
  }
};

/** 上架按钮操作 */
const handleStatus = async (row: ProductVO) => {
  try {
    // 检查商品是否有详情
    const hasDetail = await checkProductDetail(row.id);
    console.log(hasDetail);
    if (!hasDetail) {
      ElMessageBox.confirm('该商品尚未设置详情，设置详情后才能上架。是否立即去设置？', '提示', {
        confirmButtonText: '去设置',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        router.push({
          name: 'ProductDetail',
          params: { productId: row.id }
        });
      });
      return;
    }

    const text = row.status === 1 ? '下架' : '上架';
    await ElMessageBox.confirm(`确认要${text}该商品吗？`, '警告', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    });
    // 使用updateProduct API更新状态
    await updateProduct({
      ...row,
      status: row.status === 1 ? 0 : 1
    });
    ElMessage.success(`${text}成功`);
    getList();
  } catch (error) {
    console.error('操作失败:', error);
  }
};

/** 删除按钮操作 */
function handleDelete(row?: ProductVO) {
  const productIds = row?.id || ids.value;
  ElMessageBox.confirm('是否确认删除所选商品数据项?', '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    try {
      if (Array.isArray(productIds)) {
        await delProductBatch(productIds);
      } else {
        await delProduct(productIds);
      }
      getList();
      ElMessage.success('删除成功');
    } catch (error) {
      console.error('删除失败:', error);
      ElMessage.error('删除失败');
    }
  });
}

/** 每页条数改变 */
function handleSizeChange(val: number) {
  queryParams.pageSize = val;
  queryParams.pageNum = 1;
  productList.value = [];
  hasMore.value = true;
  getList();
}

/** 当前页改变 */
function handleCurrentChange(val: number) {
  queryParams.pageNum = val;
  productList.value = [];
  hasMore.value = true;
  getList();
}

/** 设置详情按钮操作 */
const handleDetail = (row: ProductVO) => {
  console.log(row);
  router.push({
    name: 'ProductDetail',
    params: { productId: row.id }
  });
};

onMounted(() => {
  getList();
  getOptions();
});

/** 获取品牌和分类选项 */
const getOptions = async () => {
  try {
    const [brandRes, categoryRes] = await Promise.all([listBrand({ pageNum: 1, pageSize: 100 }), listCategory({ pageNum: 1, pageSize: 100 })]);
    if (brandRes.code === 200) {
      brandOptions.value = brandRes.rows;
      brandCache.value.set('', brandRes.rows);
    }
    if (categoryRes.code === 200) {
      categoryOptions.value = categoryRes.rows;
      categoryCache.value.set('', categoryRes.rows);
    }
  } catch (error) {
    console.error('获取选项失败:', error);
    ElMessage.error('获取选项失败');
  }
};

// 计算属性：是否显示加载更多
const showLoadMore = computed(() => {
  return hasMore.value && productList.value.length > 0;
});

// 计算属性：是否显示没有更多数据
const showNoMore = computed(() => {
  return !hasMore.value && productList.value.length > 0;
});
</script>

<style lang="scss" scoped>
.loading-more,
.no-more {
  text-align: center;
  padding: 10px 0;
  color: #909399;
  font-size: 14px;

  .el-icon {
    margin-right: 5px;
  }
}

.search-form {
  margin-bottom: 20px;
  padding: 20px;
  background-color: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.table-container {
  background-color: #fff;
  padding: 20px;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.dialog-form {
  max-height: 500px;
  overflow-y: auto;
  padding-right: 10px;
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.status-tip {
  margin-left: 8px;
  color: var(--el-text-color-secondary);
  cursor: help;
  vertical-align: middle;
}
</style>
